package com.travel.service.Impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.travel.mapper.HotelMapper;
import com.travel.mapper.OrderMapper;
import com.travel.mapper.ScenicSpotMapper;
import com.travel.mapper.UserMapper;
import com.travel.pojo.dto.OrderDTO;
import com.travel.pojo.dto.OrderQueryDTO;

import com.travel.pojo.dto.PageDTO;
import com.travel.pojo.dto.ResourceRankingDTO;
import com.travel.pojo.entity.Order;
import com.travel.pojo.vo.*;
import com.travel.service.IOrderService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {

    private final UserMapper userMapper;

    private final ScenicSpotMapper scenicSpotMapper;

    private final HotelMapper hotelMapper;

    private final OrderMapper orderMapper;

    @Override
    public PageDTO<OrderVO> pageOrder(OrderQueryDTO orderQueryDTO) {
        Long id = orderQueryDTO.getId();
        Integer status = orderQueryDTO.getStatus();
        LocalDateTime createdAt = orderQueryDTO.getCreatedAt();
        Integer resourceType = orderQueryDTO.getResourceType();
        Long userId = orderQueryDTO.getUserId();

        Page<Order> orderPage = Page.of(orderQueryDTO.getPage(), orderQueryDTO.getPageSize());

        Page<Order> page = lambdaQuery().eq(id != null, Order::getId, id)
                .eq(status != null, Order::getStatus, status)
                .eq(resourceType != null, Order::getResourceType, resourceType)
                .eq(userId != null, Order::getUserId, userId)
                .ge(createdAt != null, Order::getCreatedAt, createdAt != null ? createdAt.toLocalDate().atStartOfDay() : null)
                .lt(createdAt != null, Order::getCreatedAt, createdAt != null ? createdAt.plusDays(1).toLocalDate().atStartOfDay() : null)
                .page(orderPage);
        List<OrderVO> collect = page.getRecords().stream().map(order -> {
            return BeanUtil.copyProperties(order, OrderVO.class);
        }).collect(Collectors.toList());
        PageDTO<OrderVO> orderVOPageDTO = new PageDTO();
        orderVOPageDTO.setList(collect);
        orderVOPageDTO.setPages((int) page.getPages());
        orderVOPageDTO.setTotal((int) page.getTotal());
        return orderVOPageDTO;
    }

    @Override
    public void updateOrder(Long id, OrderDTO orderDTO) {

    }

    @Override
    public DashboardVO getDashboard() {
        //用户数
        Integer userTotal = userMapper.selectCount(null).intValue();
        //景区数
        Integer scenicTotal = scenicSpotMapper.selectCount(null).intValue();
        //酒店数
        Integer hotelTotal = hotelMapper.selectCount(null).intValue();
        //订单数
        Integer todayOrder = orderMapper.selectCount(null).intValue();
        //
        OrderTrend orderTrend = getLast7DaysOrderTrend();
        //构造景区排行榜 ， 订单数
        Integer limit = 10;
        List<ResourceRankingDTO> scenicRankingDTO = orderMapper.selectScenicRanking(limit);
        //酒店排行榜
        List<ResourceRankingDTO> hotelRankingDTO = orderMapper.selectHotelRanking(limit);

        List<ScenicRanking> scenicRanking = scenicRankingDTO.stream().map(scenicRankingDto -> {
            return BeanUtil.copyProperties(scenicRankingDto, ScenicRanking.class);
        }).collect(Collectors.toList());
        List<HotelRanking> hotelRanking = hotelRankingDTO.stream().map(hotelRankingDto -> {
            return BeanUtil.copyProperties(hotelRankingDto, HotelRanking.class);
        }).collect(Collectors.toList());



        return DashboardVO.builder()
                .userTotal(userTotal)
                .scenicTotal(scenicTotal)
                .hotelTotal(hotelTotal)
                .todayOrder(todayOrder)
                .orderTrend(orderTrend)
                .hotelRanking(hotelRanking)
                .scenicRanking(scenicRanking)
                .build();
    }

    private OrderTrend getLast7DaysOrderTrend() {
        // 1. 计算日期范围（最近7天）
        Calendar calendar = Calendar.getInstance();
        Date endDate = calendar.getTime();
        calendar.add(Calendar.DAY_OF_MONTH, -6);
        Date startDate = calendar.getTime();

        // 2. 执行查询
        List<OrderTrendVO> dbResults = orderMapper.selectOrderTrend(startDate, endDate);

        // 3. 转换为Map便于查找
        Map<String, OrderTrendVO> resultMap = dbResults.stream()
                .collect(Collectors.toMap(OrderTrendVO::getDate, Function.identity()));

        // 4. 初始化7天数据容器
        String[] dates = new String[7];
        List<Integer> scenicData = new ArrayList<>(7);
        List<Integer> hotelData = new ArrayList<>(7);

        SimpleDateFormat sdf = new SimpleDateFormat("MM-dd");
        calendar.setTime(startDate);

        // 5. 填充数据（确保7天完整）
        for (int i = 0; i < 7; i++) {
            String currentDate = sdf.format(calendar.getTime());
            dates[i] = currentDate;

            OrderTrendVO dailyData = resultMap.get(currentDate);
            scenicData.add(dailyData != null ? dailyData.getScenicCount() : 0);
            hotelData.add(dailyData != null ? dailyData.getHotelCount() : 0);

            calendar.add(Calendar.DAY_OF_MONTH, 1);
        }

        // 6. 构建返回对象
        return new OrderTrend(dates, scenicData, hotelData);
    }
}
